package api

import (
	"github.com/cihub/seelog"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"net/http"
	"shop/config/constant"
	"shop/dao"
	"shop/entity"
	"shop/service"
	"shop/utils/convertutil"
	"shop/utils/result"
	"shop/utils/sessionutil"
	"shop/utils/wxpay"
)

// OrderPay 订单支付
func OrderPay(ctx *gin.Context) {
	shopId := sessionutil.GetShopIdFromCtx(ctx)
	orderNo := ctx.Param("orderNo")
	userId := sessionutil.GetUserIdFromCtx(ctx)
	payType := ctx.Query("payType")
	if payType != wxpay.TradeTypeJsapi && payType != wxpay.TradeTypeNative && payType != wxpay.TradeTypeApp {
		result.RenderResult(ctx, result.Fail("不支持该支付类型: "+payType))
		return
	}
	result.RenderResult(ctx, service.OrderPay(shopId, userId, orderNo, payType))
}

// WeixinPayNotify 微信支付回调
/*
返回示例：
<xml>
	<appid><![CDATA[wxa873ca2845a453df]]></appid>
	<bank_type><![CDATA[OTHERS]]></bank_type>
	<cash_fee><![CDATA[8]]></cash_fee>
	<fee_type><![CDATA[CNY]]></fee_type>
	<is_subscribe><![CDATA[N]]></is_subscribe>
	<mch_id><![CDATA[1618112867]]></mch_id>
	<nonce_str><![CDATA[PsPBguvGKbcLYKxdqutQ]]></nonce_str>
	<openid><![CDATA[ogbA_44fnEu4aNnnieP0XPr_Is_0]]></openid>
	<out_trade_no><![CDATA[1640767186502273]]></out_trade_no>
	<result_code><![CDATA[SUCCESS]]></result_code>
	<return_code><![CDATA[SUCCESS]]></return_code>
	<sign><![CDATA[AA86565B845B1DDB1E17E34AAC3B71B2]]></sign>
	<time_end><![CDATA[20211229163959]]></time_end>
	<total_fee>8</total_fee>
	<trade_type><![CDATA[NATIVE]]></trade_type>
	<transaction_id><![CDATA[4200001311202112296206282895]]></transaction_id>
</xml>
*/
func WeixinPayNotify(ctx *gin.Context) {
	xmlRes, _ := ioutil.ReadAll(ctx.Request.Body)
	seelog.Infof("微信支付回调：%s", xmlRes)
	res := convertutil.XmlToMap(string(xmlRes))
	shop := service.GetShopByWxPayMchId(convertutil.ParseInt(res["mch_id"]))
	msg := "OK"
	if !(wxpay.NewClient(shop.WxMpAppId, shop.WxPayMchId, shop.WxPayApiKey).ValidSign(res)) {
		msg = "验签失败"
	} else if res["return_code"] == "SUCCESS" && res["result_code"] == "SUCCESS" {
		// 插入微信交易号和支付金额, 自己保证幂等性
		rowsAffected := dao.GetTx().Table(entity.TableNameOrderInfo).Where("order_no=?", res["out_trade_no"]).
			UpdateColumns(map[string]interface{}{
				"wx_pay_transaction_id": res["transaction_id"],
				"pay_price":             res["total_fee"],
				"pay_time":              convertutil.ParseDataStandSerialPattern(res["time_end"]).Unix() * 1000,
				"order_status":          constant.OrderStatusWaitSend,
			}).Commit().RowsAffected
		if rowsAffected == 1 {
			service.PrinterOrder(res["out_trade_no"])
		} else {
			msg = "重复处理"
		}
	}
	ctx.XML(http.StatusOK, gin.H{
		"return_code": "SUCCESS",
		"return_msg":  msg,
	})
}
